/*
Copyright (C) 2022-2024 Inspur Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package controller

import (
	"did-service/auth"
	"did-service/bean/model"
	"did-service/common/constant"
	"did-service/common/db"
	"did-service/common/http"
	"did-service/config"
	"fmt"
	"strconv"

	"github.com/emicklei/go-restful"
)

// 申请创建did
func (dc *DidController) CreateDid(req *restful.Request, resp *restful.Response) {
	walletId := auth.GetCurrentWalletId(req)
	_, err := dc.srv.CreateDid(walletId)
	if err != nil {
		log.Errorf("create did error: %v", err)
		http.Failed(resp, "申请失败")
		return
	}
	http.Ok(resp, "申请成功")
}

// 获取did document
func (dc *DidController) GetDidDocument(req *restful.Request, resp *restful.Response) {
	id := req.PathParameter("id")
	document, err := dc.srv.GetDidDocument(id)
	if err != nil {
		log.Errorf("get did document error: %v", err)
		http.Failed(resp, "获取失败")
		return
	}
	if document == nil {
		log.Errorf("document is not exist, id[%s]", id)
		http.Failed(resp, "DID文档不存在")
		return
	}

	keys, err := dc.srv.ListKeyByDid(document.Did)
	if err != nil {
		log.Errorf("get keys by did error: %v", err)
		http.Failed(resp, "获取失败")
		return
	}
	keyPairs := make([]model.KeyPair, 0)
	for _, d := range keys {
		keyPair := model.KeyPair{}
		keyPair.Id = d.KeyId
		keyPair.Type = constant.DefaultKeyAlgo
		keyPair.PublicKeyHex = d.PubKey
		keyPair.PrivateKeyHex = d.PrvKey
		keyPairs = append(keyPairs, keyPair)
	}

	services := make([]model.Service, 0)
	service := model.Service{}
	service.Id = document.Did + constant.DefaultServiceResolveSubfix
	service.Type = constant.DefaultServiceResolveType
	service.ServiceEndpoint = config.Get("did.endpoint", constant.DefaultServiceResolveEndpoint) + constant.DidResolveUrlSuffix
	services = append(services, service)

	proof := model.Proof{
		Type:           constant.DefaultKeyAlgo,
		Creator:        document.ProofCreator,
		SignatureValue: document.ProofSignature,
	}

	result := model.DocumentDetail{
		Document: model.Document{
			Context:        constant.DefaultContext,
			Id:             document.Did,
			Version:        document.Version,
			Created:        document.CreatedTime.Format(constant.TimeLayout),
			Updated:        document.UpdatedTime.Format(constant.TimeLayout),
			KeyPairs:       keyPairs,
			Authentication: []string{document.AuthPubKey},
			Recovery:       []string{document.RecoveryPubKey},
			Service:        services,
			Proof:          proof,
		},
		TxId: document.TxId,
	}

	http.OkWithData(resp, "获取成功", result)
}

// DidDropDownList did下拉列表
func (dc *DidController) ListDidEnum(req *restful.Request, resp *restful.Response) {
	var (
		walletId = auth.GetCurrentWalletId(req)
	)
	didList, err := dc.srv.GetDidListByWalletId(walletId)
	if err != nil {
		commonHttpErr(fmt.Sprintf("find did list err %s", err.Error()),
			"查找出错", resp)
		return
	}
	ret := &model.DidDropdownList{
		List: didList,
	}
	http.OkWithData(resp, "ok", ret)
}

// DidPageList did分页列表
func (dc *DidController) ListDidPage(req *restful.Request, resp *restful.Response) {
	var (
		spDid       = req.QueryParameter("did")
		walletId    = auth.GetCurrentWalletId(req)
		err         error
		strPageSize = req.QueryParameter("pageSize")
		strPageNo   = req.QueryParameter("pageNo")

		pageNo   = 1
		pageSize = 5
	)

	if strPageNo != "" {
		pageNo, _ = strconv.Atoi(strPageNo)
	}

	if strPageSize != "" {
		pageSize, _ = strconv.Atoi(strPageSize)
	}

	var (
		pageInfo *db.Page
	)
	// 指定搜索
	if spDid != "" {
		pageInfo, err = dc.srv.GetDidSpPage(walletId, spDid, pageNo, pageSize)
	} else {
		// 分页查找
		pageInfo, err = dc.srv.GetDidPage(walletId, pageNo, pageSize)
	}

	if err != nil {
		commonHttpErr(fmt.Sprintf("page list err %s", err.Error()),
			"查找出错", resp)
		return
	}

	http.OkWithData(resp, "ok", pageInfo)
}

func (dc *DidController) DeleteDid(req *restful.Request, resp *restful.Response) {
	id := req.PathParameter("id")
	err := dc.srv.DeleteDid(id)
	if err != nil {
		log.Errorf("delete did error: %v", err)
		if err == constant.ErrorDidUsed {
			http.Failed(resp, "DID已被用于注册发证方，不能删除")
			return
		}
		http.Failed(resp, "删除失败")
		return
	}
	http.Ok(resp, "删除成功")
}
